package com.matt.service.impl;

import com.matt.domain.course.CoursePlanClasses;
import com.matt.foundation.constant.*;
import com.matt.foundation.dto.AreaSettingDTO;
import com.matt.commons.dto.sso.StaffAreaDTO;
import com.matt.foundation.query.ClassesCoursePlanQuery;
import com.matt.foundation.vo.course.WebCoursePlanListVo;
import com.matt.repository.base.ClassesCoursePlanRepository;
import com.matt.repository.course.CoursePlanClassesRepository;
import com.matt.repository.nursery.NurseryScheduleCheckRepository;
import com.matt.service.CourseAuditService;
import com.matt.service.NoticeMessageService;
import com.matt.service.remoteCall.SsoCallService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import javax.transaction.Transactional;
import java.util.*;

/**
 * *******************************
 * Created by Ron.
 * form com.matt
 * on 2018/11/28
 * *******************************
 */
@Service
public class CourseAuditServiceImpl implements CourseAuditService {

    @Autowired
    private SsoCallService ssoCallService;

    @Autowired
    private ClassesCoursePlanRepository classesCoursePlanRepository;

    @Autowired
    private CoursePlanClassesRepository coursePlanClassesRepository;

    @Autowired
    private NoticeMessageService noticeMessageService;

    @Autowired
    private NurseryScheduleCheckRepository nscRepository;

    @Override
    public Map getAuditor(String areaId) {
        //获取园区园长列表
    	//List<StaffAreaDTO> staffLeaderList = ssoCallService.getStaffByPlatformAndRoleAndArea(CommonConstant.TEACH_PLATFORM_ID, new String[]{PermissionConstant.Role.GARDEN_LEADER.codeOf()}, areaId);
    	 //获取老师列表
        //TODO fix this
    	List<StaffAreaDTO> staffList = null; //ssoCallService.getStaffByPlatformAndRoleAndArea(CommonConstant.TEACH_PLATFORM_ID, new String[]{PermissionConstant.Role.TEACHER.codeOf()}, areaId);
    	
    	//幼托班是否开启早教课程审核，0是，1否
        AreaSettingDTO nurserySetting = ssoCallService.getAreaSetting(CommonConstant.NURSERY_AUDITOR_OPEN_KEY, areaId);
        //早教班是否开启早教课程审核，0是，1否
        AreaSettingDTO earlySetting = ssoCallService.getAreaSetting(CommonConstant.EARLY_AUDITOR_OPEN_KEY, areaId);
        //是否开启托班一日生活流程审核，0是，1否
        AreaSettingDTO liveSetting = ssoCallService.getAreaSetting(CommonConstant.LIVE_AUDITOR_OPEN_KEY, areaId);
        //是否开启园区自建课程流程审核，0是，1否
        AreaSettingDTO areaBuildSetting = ssoCallService.getAreaSetting(CommonConstant.AREA_BUILD_OPEN_KEY, areaId);
        Map map = new HashMap();
        map.put("staffList", staffList);
        //设置扩展关联老师ID
        map.put("nurseryTeacherId", Objects.isNull(nurserySetting) ? "" : nurserySetting.getExtension());
        map.put("nurseryIsOpen", Objects.isNull(nurserySetting) ? 1 : Integer.valueOf(nurserySetting.getValue()));
        map.put("earlyTeacherId", Objects.isNull(earlySetting) ? "" : earlySetting.getExtension());
        map.put("earlyIsOpen", Objects.isNull(earlySetting) ? 1 : Integer.valueOf(earlySetting.getValue()));
        map.put("liveTeacherId", Objects.isNull(liveSetting) ? "" : liveSetting.getExtension());
        map.put("liveIsOpen", Objects.isNull(liveSetting) ? 1 : Integer.valueOf(liveSetting.getValue()));
        map.put("areaBuildIsOpen", Objects.isNull(areaBuildSetting) ? 1 : Integer.valueOf(areaBuildSetting.getValue()));
        map.put("areaBuildTeacherId", Objects.isNull(areaBuildSetting) ? "" : areaBuildSetting.getExtension());

        return map;
    }

    @Override
    public Map getAuditorSetting(String areaId) {
        AreaSettingDTO nurserySetting = ssoCallService.getAreaSetting(CommonConstant.NURSERY_AUDITOR_OPEN_KEY, areaId);
        AreaSettingDTO earlySetting = ssoCallService.getAreaSetting(CommonConstant.EARLY_AUDITOR_OPEN_KEY, areaId);
        AreaSettingDTO liveSetting = ssoCallService.getAreaSetting(CommonConstant.LIVE_AUDITOR_OPEN_KEY, areaId);
        Map map = new HashMap();
        map.put("nurseryTeacherId", Objects.isNull(nurserySetting) ? "" : nurserySetting.getExtension());
        map.put("nurseryIsOpen", Objects.isNull(nurserySetting) ? 1 : Integer.valueOf(nurserySetting.getValue()));
        map.put("earlyTeacherId", Objects.isNull(earlySetting) ? "" : earlySetting.getExtension());
        map.put("earlyIsOpen", Objects.isNull(earlySetting) ? 1 : Integer.valueOf(earlySetting.getValue()));
        map.put("liveTeacherId", Objects.isNull(liveSetting) ? "" : liveSetting.getExtension());
        map.put("liveIsOpen", Objects.isNull(liveSetting) ? 1 : Integer.valueOf(liveSetting.getValue()));
        return map;
    }

    @Override
    public Map getAuditor(String areaId, String key) {
        AreaSettingDTO areaSetting = ssoCallService.getAreaSetting(key, areaId);
        Map map = new HashMap();
        map.put("auditor", Objects.isNull(areaSetting) ? "" : areaSetting.getExtension());
        map.put("ipOpen", Objects.isNull(areaSetting) ? 1 : Integer.valueOf(areaSetting.getValue()));
        return map;
    }

    @Transactional
    @Override
    public Boolean addAuditor(String areaId, String teacherId, Integer isOpen, Integer category) {
        if (CourseConstant.Category.EARLY.codeOf() == category) {
            ssoCallService.addAreaSetting(CommonConstant.EARLY_AUDITOR_OPEN_KEY, String.valueOf(isOpen), "是否开启早教课程审核，0是，1否", teacherId, areaId);
            noticeMessageService.deleteByLinkIdAndCategory(areaId, NoticeMessageConstant.Category.EARLY_AUDITOR.codeOf());
        }
        if (CourseConstant.Category.NURSERY.codeOf() == category) {
            ssoCallService.addAreaSetting(CommonConstant.NURSERY_AUDITOR_OPEN_KEY, String.valueOf(isOpen), "是否开启早教课程审核，0是，1否", teacherId, areaId);
            noticeMessageService.deleteByLinkIdAndCategory(areaId, NoticeMessageConstant.Category.NURSERY_AUDITOR.codeOf());
        }
        if (CourseConstant.Category.NURSERY_DAILY_LIVE.codeOf() == category) {
            ssoCallService.addAreaSetting(CommonConstant.LIVE_AUDITOR_OPEN_KEY, String.valueOf(isOpen), "是否开启托班一日生活流程审核，0是，1否", teacherId, areaId);
            noticeMessageService.deleteByLinkIdAndCategory(areaId, NoticeMessageConstant.Category.LIVE_AUDITOR.codeOf());
        }
        if (CourseConstant.Category.AREA_BUILD.codeOf() == category) {
            ssoCallService.addAreaSetting(CommonConstant.AREA_BUILD_OPEN_KEY, String.valueOf(isOpen), "是否开启园区自建课程审核，0是，1否", teacherId, areaId);
            noticeMessageService.deleteByLinkIdAndCategory(areaId, NoticeMessageConstant.Category.AREABUILD_AUDITOR.codeOf());
        }
        if (CourseConstant.Category.KX_THEME.codeOf() == category) {
            ssoCallService.addAreaSetting(CommonConstant.KXTHEME_AUDITOR_OPEN_KEY, String.valueOf(isOpen), "是否开启康轩主课程审核，0是，1否", teacherId, areaId);
            noticeMessageService.deleteByLinkIdAndCategory(areaId, NoticeMessageConstant.Category.KXTHEME_AUDITOR.codeOf());
        }
        
        return true;
    }

    @Override
    public Boolean needAudit(String areaId, Integer category) {
        if (CourseConstant.Category.NURSERY.codeOf() == category) {
            AreaSettingDTO nurserySetting = ssoCallService.getAreaSetting(CommonConstant.NURSERY_AUDITOR_OPEN_KEY, areaId);
            return Objects.isNull(nurserySetting) ? false : 0 == Integer.valueOf(nurserySetting.getValue());
        } else if (CourseConstant.Category.EARLY.codeOf() == category) {
            AreaSettingDTO earlySetting = ssoCallService.getAreaSetting(CommonConstant.EARLY_AUDITOR_OPEN_KEY, areaId);
            return Objects.isNull(earlySetting) ? false : 0 == Integer.valueOf(earlySetting.getValue());
        }
        return false;
    }

    @Override
    public Page<WebCoursePlanListVo> getCourseList(ClassesCoursePlanQuery query) {
        List<WebCoursePlanListVo> list = classesCoursePlanRepository.findPrepareByConditions(query);

        Long count = classesCoursePlanRepository.countPrepareByConditions(query);
        return new PageImpl(list, PageRequest.of(query.getPageNum(), query.getPageSize()), count);
    }

    @Transactional
    @Override
    public Boolean audit(String coursePlanClassesId, Integer opinion) {
        CoursePlanClasses coursePlanClasses = coursePlanClassesRepository.getOne(coursePlanClassesId);
        if (CourseConstant.PrepareStatus.REJECTED.codeOf() == opinion) {
            coursePlanClasses.setPrepareStatus(opinion);

            if (coursePlanClasses.getCategory() == CourseConstant.Category.NURSERY.codeOf()){
                noticeMessageService.generateThemeCourseRejected(coursePlanClassesId);
            }else if (coursePlanClasses.getCategory() == CourseConstant.Category.EARLY.codeOf()){
                noticeMessageService.generateEarlyCourseRejected(coursePlanClassesId);
            }else if (coursePlanClasses.getCategory() == CourseConstant.Category.KX_THEME.codeOf()){
                noticeMessageService.generateKXThemeCourseRejected(coursePlanClassesId);
            }
        } else if (CourseConstant.PrepareStatus.APPROVED.codeOf() == opinion) {
            coursePlanClasses.setPrepareStatus(opinion);

            if (coursePlanClasses.getCategory() == CourseConstant.Category.NURSERY.codeOf()) {
                noticeMessageService.deleteByLinkIdAndCategory(coursePlanClassesId, NoticeMessageConstant.Category.THEME_COURSE_AUDIT.codeOf());
            } else if (coursePlanClasses.getCategory() == CourseConstant.Category.EARLY.codeOf()){
                noticeMessageService.deleteByLinkIdAndCategory(coursePlanClassesId, NoticeMessageConstant.Category.EARLY_COURSE_AUDIT.codeOf());      
            } else if (coursePlanClasses.getCategory() == CourseConstant.Category.KX_THEME.codeOf()){
                noticeMessageService.deleteByLinkIdAndCategory(coursePlanClassesId, NoticeMessageConstant.Category.KXTHEME_COURSE_AUDIT.codeOf());      
            }
        }
        coursePlanClassesRepository.save(coursePlanClasses);

        return true;
    }

    @Override
    public Long nonAuditCount(String areaId, String staffId) {
        ClassesCoursePlanQuery query = new ClassesCoursePlanQuery();
        query.setAreaId(areaId);
        query.setPrepareStatus(CourseConstant.PrepareStatus.NON_AUDIT.codeOf());
        query.setCourseStatus(CourseConstant.CourseStatus.STARTING.codeOf());
        //Long count = classesCoursePlanRepository.countPrepareByConditions(query);

        //获取审核权限
        Map auditor = getAuditorSetting(areaId);
        Long nurseryCount = 0L;
        Long earlyCount = 0L;
        Long liveCount = 0L;

        //有权限时，查询主题课待审核数
        if (StringUtils.equals(staffId, (String) auditor.get("nurseryTeacherId"))) {
            //托班主题课
            query.setCourseCategory(CourseConstant.Category.NURSERY.codeOf());
            nurseryCount = classesCoursePlanRepository.countPrepareByConditions(query);
        }
        //有权限时，查询早教课待审核数
        if (StringUtils.equals(staffId, (String) auditor.get("earlyTeacherId"))) {
            //早教课程
            query.setCourseCategory(CourseConstant.Category.EARLY.codeOf());
            earlyCount = classesCoursePlanRepository.countPrepareByConditions(query);
        }
        //有权限时，查询托班一日生活流程待审核数
        if (StringUtils.equals(staffId, (String) auditor.get("liveTeacherId"))) {
            liveCount = nscRepository.count((root, queryTemp, cb) -> {
                List<Predicate> predicates = new ArrayList<>();
                predicates.add(cb.equal(root.get("status").as(Integer.class), NurseryScheduleConstant.CheckStatus.WAIT_CHECK.codeOf()));
                predicates.add(cb.equal(root.get("areaId").as(String.class), areaId));
                return queryTemp.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
            });
        }
        return nurseryCount + earlyCount + liveCount;
    }


    @Override
    public Boolean isDisplayMenu(String staffId, String areaId) {
        AreaSettingDTO nurserySetting = ssoCallService.getAreaSetting(CommonConstant.NURSERY_AUDITOR_OPEN_KEY, areaId);
        if (Objects.nonNull(nurserySetting) && staffId.equals(nurserySetting.getExtension()))
            return true;

        AreaSettingDTO earlySetting = ssoCallService.getAreaSetting(CommonConstant.EARLY_AUDITOR_OPEN_KEY, areaId);
        if (Objects.nonNull(earlySetting) && staffId.equals(earlySetting.getExtension()))
            return true;

        AreaSettingDTO planSetting = ssoCallService.getAreaSetting(CommonConstant.LIVE_AUDITOR_OPEN_KEY, areaId);
        if (Objects.nonNull(planSetting) && staffId.equals(planSetting.getExtension()))
            return true;
        return false;
    }

	@Override
	public Boolean auditByCoursePlanClasses(CoursePlanClasses coursePlanClasses) {
		// CoursePlanClasses coursePlanClasses = coursePlanClassesRepository.getOne(coursePlanClassesId);
	        
	            coursePlanClasses.setPrepareStatus(CourseConstant.PrepareStatus.PREPARED.codeOf());

	            if(coursePlanClasses.getCategory() == CourseConstant.Category.NURSERY.codeOf()) {
	                noticeMessageService.deleteByLinkIdAndCategory(coursePlanClasses.getId(), NoticeMessageConstant.Category.THEME_COURSE_AUDIT.codeOf());
	            }else if(coursePlanClasses.getCategory() == CourseConstant.Category.EARLY.codeOf()){
	                noticeMessageService.deleteByLinkIdAndCategory(coursePlanClasses.getId(), NoticeMessageConstant.Category.EARLY_COURSE_AUDIT.codeOf());
	            }
	                coursePlanClassesRepository.save(coursePlanClasses);

	                return true;
	            }

	@Override
	public Page<WebCoursePlanListVo> getKXCourseList(ClassesCoursePlanQuery query) {
		    List<WebCoursePlanListVo> list = classesCoursePlanRepository.findKXPrepareByConditions(query);

	        Long count = classesCoursePlanRepository.countKXPrepareByConditions(query);
	        return new PageImpl(list, PageRequest.of(query.getPageNum(), query.getPageSize()), count);
	}

	@Override
	public List<WebCoursePlanListVo> getKXPrepareCourseTeacherList(ClassesCoursePlanQuery query) {
		 List<WebCoursePlanListVo> list = classesCoursePlanRepository.findKXPrepareByConditions(query);
		 return list;
	   }
     }
